//css_import credentials;
using System;
using System.Net;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Forms;
using System.Text;
using System.IO;
using CSScriptLibrary;
using csscript;

namespace Scripting
{
    class UpdateScript
    {
        [STAThread]
        static public void Main(string[] args)
        {
            //Debug.Assert(false);
            if (args.Length == 0 || args[0].ToLower() == "-?" || args[0].ToLower() == "/?")
                Console.WriteLine("Usage: cscscript wsdl url file [/opt: [wsdl_option_1]...[wsdl_option_N]] [/new] ...\n" +
                                    "Generates C# code for WebServiceClient.\n  " +
                                    "  url  - Url of a WSDL contract.\n  " +
                                    "  file - The filename for the generated proxy code.\n  " +
                                    "  /opt - list of 'row' wsdl.exe command line options.\n" +
                                    "  /new - Generate C# file only if it does not exist yet.");
            else
            {
                string wsdlExe = Environment.ExpandEnvironmentVariables(@"%CSSCRIPT_DIR%\lib\tools\wsdl.exe");
                string url = args[0];
                string csModule = (args[1].EndsWith(".cs") ? args[1] : (args[1] + ".cs"));
                string options = "";

                foreach (var arg in args)
                {
                    if (arg.ToLower() == "/new" && File.Exists(csModule))
                        return; //no need to generate proxy file as it already exists

                    if (arg.StartsWith("/opt:"))
                        options = arg.Substring("/opt:".Length).Trim();
                }

                bool useProxyAuthentication = false;

                while (true)
                {
                    try
                    {
                        if (!File.Exists(wsdlExe))
                            throw new FileNotFoundException("Cannot find " + wsdlExe + " utility.");

                        string user = null, pw = null;

                        if (useProxyAuthentication)
                            if (!AuthenticationForm.GetCredentials(ref user, ref pw, "Proxy Authentication"))
                                return;

                        string output = "";

                        if (TestURL(url, user, pw))
                        {
                            csModule = ResolveOutputLocation(csModule);

                            string cmdLine = string.Empty;

                            if (user != null)
                                cmdLine = "\"/proxyusername:" + user + "\" \"/proxypassword:" + pw + "\" \"/o:" + csModule + "\" " + url;

                            else
                                cmdLine = "\"/o:" + csModule + "\" " + url;

                            if (options != "")
                                cmdLine += " \"" + options + "\"";

                            output = RunApp(wsdlExe, cmdLine);
                        }
                        if (!File.Exists(csModule))
                            throw new FileNotFoundException("Cannot create " + csModule + " file.");
                        return;
                    }
                    catch (Exception e)
                    {
                        if (e is System.Net.WebException && e.Message == "The remote server returned an error: (407) Proxy Authentication Required.")
                        {
                            if (useProxyAuthentication)
                                Console.WriteLine(e.Message);

                            useProxyAuthentication = true;
                            continue;
                        }
                        throw e;
                    }
                }
            }
        }

        static string ResolveOutputLocation(string file)
        {
            string primaryScriptFile = Environment.GetEnvironmentVariable("EntryScript");

            if (primaryScriptFile != null && CSScript.GlobalSettings.HideAutoGeneratedFiles == Settings.HideOptions.HideAll)
                return Path.Combine(CSSEnvironment.GetCacheDirectory(primaryScriptFile), Path.GetFileName(file));
            else if (primaryScriptFile != null)
                return Path.Combine(Path.GetDirectoryName(primaryScriptFile), file);
            else
                return Path.GetFullPath(file);
        }

        static bool TestURL(string url, string proxyUser, string proxyPw)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            if (proxyUser != null)
            {
                GlobalProxySelection.Select.Credentials = new NetworkCredential(proxyUser, proxyPw);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            return true;
        }

        static string RunApp(string app, string args)
        {
            Process myProcess = new Process();
            myProcess.StartInfo.FileName = app;
            myProcess.StartInfo.Arguments = args;
            myProcess.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
            myProcess.StartInfo.UseShellExecute = false;
            myProcess.StartInfo.RedirectStandardOutput = true;
            myProcess.StartInfo.CreateNoWindow = true;

            myProcess.Start();

            StringBuilder sb = new StringBuilder();
            string line = null;

            while (null != (line = myProcess.StandardOutput.ReadLine()))
            {
                sb.Append(line);
                sb.Append("\r\n");
            }
            myProcess.WaitForExit();
            return sb.ToString();
        }
    }
}